All files / src/app/api/reviews/[reviewId] route.ts

93.61% Statements 88/94
77.27% Branches 17/22
100% Functions 2/2
93.61% Lines 88/94

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 951x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x     8x 8x 8x 8x 8x 1x 1x 7x 7x 7x 7x 7x 8x 3x 1x 1x 2x 2x 2x 2x 4x 4x 8x 3x 1x 1x 2x 3x     2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x     3x 3x 3x 3x 3x 1x 1x 2x 2x 1x 1x 1x 1x 1x  
import { NextRequest, NextResponse } from "next/server";
import { Session } from "next-auth";
import {
  updateReview,
  deleteReview,
  markReviewHelpful } from "@/lib/ecommerce";
import {
  withErrorHandling,
  withUser,
  successResponse,
  ApiError } from "@/lib/api";
import { RouteContext } from "@/lib/api/middleware";
import type { AuthenticatedUser } from '@/lib/api/middleware/types';
 
/**
 * PATCH /api/reviews/[reviewId]
 * Update a review or mark as helpful (requires authentication)
 */
async function handlePatch(
  request: NextRequest,
  context: RouteContext | undefined,
  _session: Session,
  user: AuthenticatedUser
): Promise<NextResponse> {
  if (!context?.params) {
    throw ApiError.invalidId("review");
  }
 
  const { reviewId } = await context.params;
  const id = parseInt(reviewId);
 
  if (isNaN(id)) {
    throw ApiError.invalidId("review");
  }
 
  const body = await request.json();
  const { action, rating, comment, helpful } = body;
 
  // Handle mark as helpful
  if (action === "helpful") {
    if (typeof helpful !== "boolean") {
      throw ApiError.validation("helpful must be a boolean");
    }
 
    const result = await markReviewHelpful(id, user.id, helpful);
    return successResponse(result);
  }
 
  // Handle edit
  if (action === "edit") {
    if (rating === undefined) {
      throw ApiError.validation("Rating is required");
    }
 
    if (rating < 1 || rating > 5) {
      throw ApiError.validation("Rating must be between 1 and 5");
    }
 
    const review = await updateReview(id, user.id, rating, comment);
    return successResponse(review);
  }
 
  throw ApiError.validation("Invalid action. Must be 'helpful' or 'edit'");
}
 
export const PATCH = withErrorHandling(withUser(handlePatch));
 
/**
 * DELETE /api/reviews/[reviewId]
 * Delete a review (requires authentication)
 */
async function handleDelete(
  _request: NextRequest,
  context: RouteContext | undefined,
  _session: Session,
  user: AuthenticatedUser
): Promise<NextResponse> {
  if (!context?.params) {
    throw ApiError.invalidId("review");
  }
 
  const { reviewId } = await context.params;
  const id = parseInt(reviewId);
 
  if (isNaN(id)) {
    throw ApiError.invalidId("review");
  }
 
  await deleteReview(id, user.id);
 
  return successResponse({ message: "Review deleted successfully" });
}
 
export const DELETE = withErrorHandling(withUser(handleDelete));